home *** CD-ROM | disk | FTP | other *** search
- /* OVLINES.C Version 1.1
- A Line drawing toy similar to PolyScope but for the OpalVision
- INTRO:
- This hack draws lines in symmetry on the OpalVision screen. It appears
- no purpose, but is good eyecandy. An alternative use would be a screen
- blanker. This hack is in its infancy, and in response to
- requests for this sort of drawing program. It is based loosly on a program
- called IToy in AMiga Basic ( about 1986), and is written in c compiled by
- SAS brand C compiler Version 6.02.
-
- USE:
- To use, type "ovlines" at the CLI prompt. I did not bother to
- make an Icon for it yet. MAKE SURE FIRST THAT YOUR SCREENMODE IS EITHER
- NTSC OR PAL. If it is set to 800x600 or VGA results are unpredictible.
- To exit, press and hold the mouse button.
- A few options are added. Typing "ovlines l" will latch the display
- and leave the screen as of when exit was chosen as a backdrop to workbench.
- Typing "ovlines s filename" will save the screen as an IFF24 file with that
- name. If you want it in another directory, specify the complete absolute
- path. I did not use JPEG since its optimized for full 24 bits and is not
- efficient here, and the degradation is more apparent with this type of
- picture, plus it takes significantly longer. Even the IFF save uses all
- 24 bits, the pictures are actually larger than the screen! is better than
- nothing.
-
-
- THEORY:
-
- Ovlines opens an 8 bit plane screen in Hires Overscan. It then algorith
- matically generates a pallette (see PalGrad() ) that creates an array of colors
- by stepping through them with different slopes. I had tried totally random
- palettes and a single gradient and this method seemed more pleasing than
- either.
- The end points of the lines(x1,y1,x2,y2) are stepped by the interval
- x1i,x2i, etc. Four lines are created to connect to four points on the
- screen. The end points are clipped when they would get outside the screen
- and the direction is reversed. Each group is drawn with the next color
- out of 256. Color 0 is not used or affected, and that is the black back-
- ground. When all 255 colors are printed, new endpoints and intervals are
- selected, and a different design is printed. Every fourth run, the screen is
- cleared, as it becomes too cluttered after that to make out any detail.
-
-
-
-
-
- LEGAL AND PURPOSE:
- This source is copyright 1993 Jim Boros, and may be redistibuted
- by any means as long as this notice is intact. Distribution is encouraged
- by Fred Fish and the OpalVision BBS, and BIX. It may be used in whole or
- part for any noncommercial software product, especially a screen blanker.
- You may alter it and redistribute
- it, this is mainly for educational purposes, and it is hoped other program-
- mers will add to it and repost. If you alter this, please acknowledge
- the origin plus any other programmers that contributed to it by leaving
- these notices intact(you may add your credits for your additions and
- modifications). Use this at your own risk, I will not be responsible for
- any crashed machines or for any lost productivity or other damages caused
- by this product(there shouldn't be any, but must cover my a**).
-
- OpalVision is a trademark of Opal Party Ltd.
- Amiga is a trademark of Commodore- Amiga, Inc.
- Bars & Pipes is a trademark of Blue Ribbon Soundworks.
-
- This is distributed in request for these hacks, and this is to fill that
- and to educate others on OpalVision programming. It is hoped others use
- this code this way, and add their own tricks and share these with other
- OpalVision programmers. Also, it is a piece of Eye Candy for Valentines
- day and Easter.
- No set fee is requested for use of the program, however donations are
- cheerfully accepted at the address below. Future versions may be shareware
- or part of a commercial package, but will be quite economical.
-
- MY QUESTION:
- I have tried to write programs with AMiga over Opal using DualDisplay
- and AmigaPriority(). Every time it updated the Amiga overlay would flash.
- Anyone have a workaround?
-
-
- FUTURE PLANS:
- If however, you wish to see a feature added and are not a programmer
- or if you are and have a question or comment about this, leave mail to me
- (JimB) on OpalVIsion BBS or jboros on BIX, or write to Borotec below.
- I will write an AGA version of this as soon as I get an AMiga
- 4000 or better computer. If you can't wait for that, just donate one
- and I'll write it and send you a disk of it. Also, look for more
- OpalVision programs, Modules for Bars&Pipes(Blue Ribbon Soundworks)
- are being considered. An algorithmic music composition program, MIDI Math,
- is available from Borotec Inc, Box 17149, Euclid, Ohio 44117 for $29
- PPD. This turns mathmatical equations into music compositions. A version
- to run with Bars & Pipes is under development, and it has not been determined
- whether Borotec or Blue Ribbon will market.
-
-
-
-
- V1.10 J. Boros 2-13-93 */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <dos.h>
- #include <stddef.h>
- #include <math.h>
- #include <time.h>
- #include <opal/opallib.h>
- #include <graphics/gfxbase.h>
- #include <exec/memory.h>
- #include <hardware/custom.h>
- #include <proto/all.h>
-
-
- unsigned char *setpal(double hue, double sat,double lite, unsigned char *res);
- double mag_blue(double), mag_green(double),mag_red(double);
- double ITENO=255.0 ; /* 8 bit pallette instead of 6 per color */
-
-
-
- void Clean_Up(char *,UBYTE); /* my prototypes go here */
- void RandPal(void),CycleColors(void);
- void PalGrad(short,short,short),PalSmooth(short,short);
-
- #define MAXCOLORS 256
- #define DISP_W 732 /* overscan screen */
- #define DISP_H 476 /* overscan height */
-
- #define TRUE 1
- #define FALSE 0
- #define BAD 0
- #define OK 1
- #define RBMASK 0x0400
- #define MAXMODE 2 /* increase as more modes are added */
-
- #define colour color ; for programmers outside the USA
- #define Colour Color
-
- int clk[2]; /* for reading time */
- struct OpalBase *OpalBase = NULL;
- struct OpalScreen *OScrn;
-
- /* Joystick and Mouse primitive stuff.
-
- Yes, I bang the hardware but this is not for video, and is read only */
-
- __far extern struct Custom custom; /* for registers */
-
- __far UBYTE *Button = (UBYTE *)0xbfe001; /* Nasty */
- __far UWORD *RButton= (UWORD *)0xdff016; /* read right button */
- /* bit 10, use dff016 for right */
- #define RIGHT custom.joy1dat & 2
- #define LEFT custom.joy1dat & 0x200
- #define UP ( custom.joy1dat & 1 )
- #define DOWN ( custom.joy1dat & 0x100)
- #define FIRE (*Button & 0x80)
-
-
- main(argc,argv)
- int argc;
- char **argv;
- {
- long scm;
- short mode,i,x1,y1=323,x2,y2=77;
- short x1i,y1i,x2i,y2i; /* drawing variables */
- UBYTE c=1,ci,inch,argf,pm=1;
- i=0;
- mode=0; /* default to lines */
- argf=1; /* normal */
- timer(clk); /* get time */
- srand(clk[0]+clk[1]); /*reseed randomizer */
-
- printf("OVlines V1.10 Copyright J. Boros 1993 \n");
- printf("Usage: ovlines [pm] [option] [filename] \n");
- printf("Where pm =0 for random, 1 for ramped, 2 for smooth hues \n");
- printf("Hold Right Mouse Button a few sec to change Mode \n");
- x1i=x2i=y1i=y2i=9; /* default increment */
- OpalBase = (struct OpalBase *) OpenLibrary ("opal.library",0L);
- if (OpalBase==0L)
- Clean_Up ("Can't open opal.library\n",10);
- OScrn = NULL;
- scm = ILACE24 | HIRES24 | OVERSCAN24 | PALMAP24 | PLANES8 ;
- OScrn = OpenScreen24(scm) ; /* open an OpalVision Screen */
- if ( !OScrn) Clean_Up( "Cannot open OV Screen ",22);
- StopUpdate24();
- AutoSync24(FALSE);
- OVPriority();
- ci = (UBYTE) *argv[1];
- if ( (argc >=1 ) && isdigit(ci) ){
- pm= ci-48; /* if a number entered use */
- argf=2; } /* look one higher for argument */
-
- switch (pm) {/* decide what to do with palette */
- case 0: RandPal(); break; /* have utterly random palette */
- case 1: PalGrad(13,5,47); /* psuedo randomize palette */ break;
- case 2 : PalSmooth(98,60); /* create smooth palette */ break;
- }
- UpdatePalette24();
- RegWait24();
-
- /* memcpy(&OpalScreen->Palette[0],&Colours[0][0],768); */
-
-
- while (*Button &0x040) { /* try and cycle colours until button pressed */
- c++;
- if (((c&127)==0) || ( !FIRE && !(c&3)) ) { /* after each 256 line sets change pattern */
- c=1; /* don't draw bkg color */
- x1= rand() % DISP_W;
- x2=rand() %DISP_W;
- timer(clk); /* get time */
- srand(clk[0]+clk[1]); /*reseed randomizer */
- y1=rand() % DISP_H;
- y2=rand()% DISP_H; /* randimize */
- x1i=x2i=rand() &0x0F | 1;
- y1i=y2i=rand() &0x07 | 1;
-
- /* maybe I'll rand the intervals */
- i++;
- /* inch=getch(); */
- if ( !(i&7) ) {ClearQuick24(); /* clear screen every 8th run */
- UpdatePalette24(); i=0;
- }
-
- }
-
- x1+=x1i; y1+=y1i;
- x2-=x2i; y2-=y2i; /* add the increments */
- if ( UP ) { y1+=10; y2 += 10; }/* Steer it W Joystick JB 2-16 */
- if ( DOWN ) { y1-=10; y2 -=10; }
- if ( LEFT ) { x1-= 14; x2-=14; }
- if ( RIGHT) { x1+=14; x2+= 14; }
- /* clip values, keep them on screen */
- if (x1 <0) { x1 =0; x1i =x1i *(-1); }
- if (x1 >DISP_W) { x1 =DISP_W-x1i; x1i =x1i *(-1); }
- if (y1 <0) { y1 =0; y1i =y1i *(-1); }
- if (y1 >DISP_H) { y1 =DISP_H-y1i; y1i =y1i *(-1); }
- if (x2 <0) { x2 =0; x2i =x2i *(-1); }
- if (x2 >DISP_W) { x2 =DISP_W-x2i; x2i =x2i *(-1); }
- if (y2 <0) { y2 =0; y2i =y2i *(-1); }
- if (y2 >DISP_H) { y2 =DISP_H-y2i; y2i =y2i *(-1); }
- OScrn->Pen_R=256-c; /* set colour to draw NOTE WE ONLY NEED USE RED!*/
- /* now draw them */
- CycleColors();
- switch ( mode) { /* decide several shapes */
- case 0 :
- DrawLine24(OScrn,x1,y1,x2,y2);
- DrawLine24(OScrn,x1,DISP_H-y1,x2,DISP_H-y2);
- DrawLine24(OScrn,DISP_W-x1,y1,DISP_W-x2,y2);
- DrawLine24(OScrn,DISP_W-x1,DISP_H-y1,DISP_W-x2,DISP_H-y2);
- break;
- case 1 : /* try boxes */
- RectFill24(OScrn,min(x1,x2),min(y1,y2),max(x1,x2),max(y1,y2));
-
- if ( c <255) OScrn->Pen_R++; /* try incr pens */
- /* RectFill24(OScrn,DISP_W-max(x1,x2),DISP_H-max(y1,y2),
- DISP_W-min(x1,x2),DISP_H-min(y1,y2) ); */
- break;
- case 2 : /* ellipses? */
- DrawEllipse24(OScrn, (x1+x2)/2,(y1+y2)/2, abs(x1-x2)/2,abs(y1-y2)/2);
- DrawEllipse24(OScrn,DISP_W-((x1+x2)/2),DISP_H-((y1+y2)/2), abs(x1-x2)/2,abs(y1-y2)/2);
- break;
- }
- if ((!(*RButton & RBMASK)) && (!(c &3))) { /* debounsed rmb in*/
- mode++;
- if (mode >MAXMODE) mode=0; /* limit if gets too high */
- }
- WaitTOF();
- Refresh24(); /* update screen and give OS a breather for any tasks */
- Delay(1);
- } /* end of draw loop */
- if ( argc > argf) { /* we typed some extra stuff! */
- switch ((UBYTE) *argv[argf] ) { /* if we typed a command use disp as bakdrop*/
- case 'l' : /* latch display and use as backdrop */
- AmigaPriority ();
- DualDisplay24 ();
- AutoSync24 (FALSE); /* try turn off autosync */
- Delay (1);
- LatchDisplay24 (TRUE);
- break;
- case 's' : /* save as IFF file using name */
- if(argc>(argf+1))
- x1=SaveIFF24(OScrn,argv[argf+1],NULL,NULL); /* save as iff24 */
- Clean_Up("Attemped to save IFF",x1);
- }
-
- }
-
-
- Clean_Up(" Normal Exit",0);
- }
-
- void RandPal()
- {
- int i,j; /* fill palette with RANDOM or pseudorandom colours */
- for(i=3; i<(MAXCOLORS*3); i++){
- j=rand();
- OScrn->Palette[i]= (UBYTE) ((j>>3) & 0x0FF); /* try LSB's */
-
- }
-
- }
-
- void PalGrad(rm,gm,bm)
- short rm,gm,bm;
- { /* gradients depending on values entered as 'mod' values for ea colour */
- int i;
- for(i=1;i< MAXCOLORS; i++){
- OScrn->Palette[i*3] =(i*rm) &0x0ff+200 ;
- OScrn->Palette[i*3+1] =(i*gm) &0x0ff ;
- OScrn->Palette[i*3+2] =(i*bm) &0x0ff ; /* appear to cycle */
- }
-
- }
- void PalSmooth(short s,short v)
- {
- int i;
- for(i=1; i<MAXCOLORS; i++)
- setpal((double)i/256.0,s/100.0,v/100.0,&OScrn->Palette[i*3]);
- /* make a very smooth transition of hue, with high saturation */
- }
-
- void CycleColors() {
- UBYTE rl,gl,bl;
- /* cycle colors, plays 'musical' registers. Screen structure is
- global, as one slip here invites Mr. GURU
- WE DO NOT CYCLE COLOR 0, it is the black background */
-
- rl=OScrn->Palette[765]; /* get old top values R*/
- gl=OScrn->Palette[766]; /* get old top values G*/
- bl=OScrn->Palette[767]; /* get old top values B*/
- memmove(&OScrn->Palette[6],&OScrn->Palette[3],762);
- OScrn->Palette[3]=rl; /* leave color 0 alone! */
- OScrn->Palette[4]=gl;
- OScrn->Palette[5]=bl;
- UpdatePalette24(); /* make it regiter on OV */
- }
-
- void Clean_Up(error,ExitVal)
- UBYTE ExitVal;
- char *error;
- {
- if (OpalBase) {
- AmigaPriority();
- /* SingleDisplay24(); */
-
- if (OScrn) {
- CloseScreen24();
- OScrn = NULL;
- }
-
- CloseLibrary((struct Library *)OpalBase);
- OpalBase = NULL;
- }
- printf(" %s \n",error); /* tell why we quit! */
- exit(ExitVal);
- }
-
-
-
- /* conversion from HSV to RGB */
- /* derived from Computer Applications Journal Oct/Nov 92 */
- /* call setpal below to use, other routines here are subparts of setpal
- hue,sat,lite are double floating point between 0 and 1.
- res is a pointer to the red entry in the palette */
-
- unsigned char *setpal(double hue, double sat,double lite, unsigned char *res)
- {
- double red,green,blue;
- double red1,gren1,blu1,euh,sat0;
-
- if (hue <= 0.5) euh=hue+0.5; /* hue compliment */
- else euh=hue-0.5;
- sat0=2.0*lite+min((-4.0*lite) + 2.0, 0.0);
- sat0=max(sat0,0.0); /* max sat= f(lite) */
- sat0=min(sat0,1.0);
-
- blue=mag_blue(hue);
- blue=max(blue,0.0);
- blue=min(blue,1.0);
-
- blu1=mag_blue(euh);
- blu1=max(blu1,0.0);
- blu1=min(blu1,1.0);
-
- blue= ITENO * lite *(blue + ( 1.0 - sat*sat0) *blu1);
-
-
- green=mag_green(hue);
- green=max(green,0.0);
- green=min(green,1.0);
-
- gren1=mag_green(euh);
- gren1=max(gren1,0.0);
- gren1=min(gren1,1.0);
-
- green= ITENO * lite *(green + ( 1.0 - sat*sat0) *gren1);
-
-
- red=mag_red(hue);
- red=max(red,0.0);
- red=min(red,1.0);
-
- red1=mag_red(euh);
- red1=max(red1,0.0);
- red1=min(red1,1.0);
-
- red= ITENO * lite *(red + ( 1.0 - sat*sat0) *red1);
- *res= (unsigned char) red; /* stash results in BYTE buffer */
- *(res+1) =(unsigned char) green;
- *(res+2) =(unsigned char) blue;
-
-
- return(res);
- }
-
-
- double mag_red(double x) /* switch red and blue for OpalVision Compat */
- {
- double result;
- result=(max(0.3333-x,0.0)+min(x-0.16667,0.0)+max(x-0.6667,0.0)+
- min(0.8333-x,0.0))/0.1666;
- return(result);
-
- }
-
- double mag_green(double x)
- {
- double result;
- result=( x+min(0.1667-x,0.0)+min(0.5-x,0.0)+max(x-0.6667,0.0))/0.1667;
- return(result);
- }
- double mag_blue(double x)
- {
- double result;
- result=(max(x-0.3333,0.0)+min(0.5-x,0.0)+min(0.8333-x,0.0))/0.1667;
- return(result);
- }
-
-
-
-
-
-
-
-
-